#include <iostream>
#include <fstream>
//#include <mpi.h>
#include <omp.h>
#include <codecvt>
#include <locale>
//#include <sys/time.h>
#include <chrono>

#include "grid_io.hpp"
#include "grid_struct.hpp"
#include "Search.hpp"

#define datatype double

using namespace std;

/*
double mysecond()
{
    struct timeval tp;
    struct timezone tpz;
    int i = gettimeofday(&tp, &tpz);
    return ((double)tp.tv_sec * 1000 + (double)tp.tv_usec * 1e-3);
}
*/

double mysecond()
{
    using namespace std::chrono;
    auto now = high_resolution_clock::now();
    auto duration = now.time_since_epoch();
    return duration_cast<milliseconds>(duration).count();
}

int main(int argc, char **argv)
{
    const std::string src_grid_file = "../../../../../data/Grid_and_data.txt";
    // const std::string src_grid_file = "Question2/test_and_data.txt";
    const std::string dst_grid_file = "../../../../../data/Result_grid_coordinates.txt";
    const std::string output_file = "../../../../../data/Our_Answer_uniform2.txt";

    size_t totalLines_src = 0, totalLines_dst = 0;
    std::vector<FEM_struct<datatype>> OriginGridArray;
    std::vector<FEM_struct<datatype>> TargetGridArray;
    datatype axisMax[3], axisMin[3];
    datatype stride[3] = {10.0, 10.0, 10.0};
    int numGridX = 201, numGridY = 101, numGridZ = 51;
    int GirdMax[3] = {numGridX, numGridY, numGridZ}, GridMin[3] = {0, 0, 0};

    Serial_read_FEM_sourcegrid<datatype>(src_grid_file, OriginGridArray, axisMax, axisMin);
    bool is_Uniform_Grid = true;
    Serial_read_FEM_destgrid<datatype>(dst_grid_file, TargetGridArray);

    double Stime = 0.0;
    Stime = -mysecond();
    #pragma omp parallel for
    //for (auto& element : TargetGridArray){
    for (int i = 0; i < TargetGridArray.size(); ++i) {
        Uniform_Search_eqDis<FEM_struct<datatype>, datatype>(OriginGridArray, TargetGridArray[i], stride, axisMax, GirdMax, GridMin);
    }
    
    Stime += mysecond();

    Serial_store_FEM_destgrid<datatype>(output_file, TargetGridArray);

    std::cout << "Search Point Cost " << Stime << " ms." << std::endl;

    return 0;
}